<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <style>
    body {
      height: 2000px;
      /* make body scrollable, the tooltip should work after the scroll */
    }

    .tooltip {
      /* some styles for the tooltip, you can use your own instead */
      position: fixed;
      padding: 10px 20px;
      border: 1px solid #b3c9ce;
      border-radius: 4px;
      text-align: center;
      font: italic 14px/1.3 sans-serif;
      color: #333;
      background: #fff;
      box-shadow: 3px 3px 3px rgba(0, 0, 0, .3);
    }
  </style>
</head>

<body>

  <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p>
  <p>LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa LaLaLa</p>

  <button data-tooltip="the tooltip is longer than the element">Short button</button>
  <button data-tooltip="HTML<br>tooltip">One more button</button>

  <p>Scroll the page to make buttons appear on the top, check if the tooltips show up correctly.</p>


  <script>
    const span = document.createElement("span");
    span.classList.add("tooltip")
    document.addEventListener("mouseover", function(e) {
      const tip = e.target.dataset.tooltip;
      if (!tip) {
        return;
      }

      span.innerHTML = tip;
      e.target.append(span);
      const {left, top, width, height} = e.target.getBoundingClientRect();
      const tipStyle = getComputedStyle(span);

      span.style.left = `${left}px`;
      const tippaddingleft = parseInt(tipStyle.paddingLeft);
      if (width>span.offsetWidth) {
        const exleft = (width-span.offsetWidth)/2;
        span.style.left = `${left+exleft}px`;
      }
      span.style.top = `${top - parseInt(tipStyle.height)- height -5}px`;
      if (top<span.offsetHeight+5) {
        span.style.top = `${top + height +5}px`;
      }
    })
    document.addEventListener("mouseout", function(e) {
      const tip = e.target.dataset.tooltip;
      if (!tip) {
        return;
      }
      span.remove()
    })
    
  </script>

</body>
</html>